package com.fjwt.gz.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fjwt.gz.core.exception.BizException;
import com.fjwt.gz.db.dto.ACTE027StatDTO;
import com.fjwt.gz.db.dto.StatMemberNumDTO;
import com.fjwt.gz.db.entity.AgentAppEntity;
import com.fjwt.gz.db.entity.AgentInfoEntity;
import com.fjwt.gz.db.entity.StatMemberNumEntity;
import com.fjwt.gz.db.vo.ACTE027StatVO;
import com.fjwt.gz.db.vo.AgentInfoVO;
import com.fjwt.gz.db.vo.StatMemberNumVO;
import com.fjwt.gz.service.mapper.StatMemberNumMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 统计：机构会员通报表 服务实现类
 * </p>
 *
 * @author shiyonghao
 * @since 2025-07-24
 */
@Slf4j
@Service
public class StatMemberNumService extends ServiceImpl<StatMemberNumMapper, StatMemberNumEntity> {

    @Autowired
    private AgentInfoService agentInfoService;
    @Autowired
    private AgentAppService agentAppService;


    // 福利焕活福分值
    private static final Integer SCORE_VALUE = 80;
    // 首页柱形图统计天数
    static final int STAT_DAY = 15;


    /**
     * 福利焕活会员召回（机构）明细分页列表
     * @param iPage
     * @param acte027StatDTO
     * @return
     */
    public IPage<ACTE027StatVO> getAgentRecallDetails(IPage iPage, ACTE027StatDTO acte027StatDTO) {
        acte027StatDTO.setStatDate(DateUtil.beginOfDay(DateUtil.offsetDay(DateUtil.date(), -1)));
        IPage<ACTE027StatVO> page = baseMapper.getAgentRecallDetails(iPage, acte027StatDTO);

        for (ACTE027StatVO record : page.getRecords()) {
            setAgentName(record);
            // 总剩余同步旧会员数量
            record.setTotalResidueSyncMemberNum(record.getTotalOldMemberNum() - record.getTotalSyncMemberNum());
            record.setActivitySyncMemberScoreNum(record.getActivitySyncMemberNum() * SCORE_VALUE);
        }

        return page;
    }



    /**
     * 福利焕活会员召回明细分页列表
     * @param iPage
     * @param acte027StatDTO
     * @return
     */
    public IPage<ACTE027StatVO> getRecallDetails(IPage iPage, ACTE027StatDTO acte027StatDTO) {
        acte027StatDTO.setStatDate(DateUtil.beginOfDay(DateUtil.offsetDay(DateUtil.date(), -1)));
        acte027StatDTO.setTotalSyncMemberNumSortDesc(true);
        if (ObjectUtils.isNotEmpty(acte027StatDTO.getAgentNo())) {
            AgentInfoEntity agentInfo = agentInfoService.getAgentInfo(acte027StatDTO.getAgentNo());
            if (ObjectUtils.isNotEmpty(agentInfo)) {
                if (agentInfo.getLevel() < 3) {
                    acte027StatDTO.setAgentNo(null);
                    List<AgentInfoVO> agentInfoVOList = agentInfoService.querySubAgentList(acte027StatDTO.getAgentNo());
                    List<String> collect = agentInfoVOList.stream().map(AgentInfoVO::getAgentNo).collect(Collectors.toList());
                    collect.add(null);
                    acte027StatDTO.setAgentNoList(collect);
                }
            }
        }

        IPage<ACTE027StatVO> page = baseMapper.getAgentRecallDetails(iPage, acte027StatDTO);

        for (ACTE027StatVO record : page.getRecords()) {
            setAgentName(record);
            // 总剩余同步旧会员数量
            record.setTotalResidueSyncMemberNum(record.getTotalOldMemberNum() - record.getTotalSyncMemberNum());
            record.setActivitySyncMemberScoreNum(record.getActivitySyncMemberNum() * SCORE_VALUE);
            record.setTotalSyncMemberNumAvg(new BigDecimal(record.getTotalSyncMemberNum())
                    .divide(new BigDecimal(this.getDefaultValue(record.getNextAgentNum())), RoundingMode.HALF_UP));
        }

        return page;
    }

    public Integer getDefaultValue(Integer value) {
        return ObjectUtils.isEmpty(value) || 0 == value ? 1 : value;
    }

    /**
     * 对机构名称赋值
     * @param record
     */
    public void setAgentName(ACTE027StatVO record) {
        if (ObjectUtils.isNotEmpty(record.getAgentNo())) {
            if (record.getAgentNo().equals(record.getAgentNo4())) {
                record.setAgentName(record.getAgentName4());
                record.setPId(record.getAgentNo3());
                record.setPName(record.getAgentName3());
            }else if (record.getAgentNo().equals(record.getAgentNo3())) {
                record.setAgentName(record.getAgentName3());
                record.setPId(record.getAgentNo2());
                record.setPName(record.getAgentName2());
            }else if (record.getAgentNo().equals(record.getAgentNo2())) {
                record.setAgentName(record.getAgentName2());
                record.setPId(record.getAgentNo1());
                record.setPName(record.getAgentName1());
            }else if (record.getAgentNo().equals(record.getAgentNo1())) {
                record.setAgentName(record.getAgentName1());
            }
        }else {
            record.setAgentNo("自然流量");
            record.setAgentName("自然流量");
            record.setPId("自然流量");
            record.setPName("自然流量");
        }
    }

    /**
     * 对机构名称赋值
     * @param record
     */
    public void setAgentName(StatMemberNumVO record) {
        if (ObjectUtils.isNotEmpty(record.getAgentNo())) {
            if (record.getAgentNo().equals(record.getAgentNo4())) {
                record.setAgentName(record.getAgentName4());
                record.setPId(record.getAgentNo3());
                record.setPName(record.getAgentName3());
            }else if (record.getAgentNo().equals(record.getAgentNo3())) {
                record.setAgentName(record.getAgentName3());
                record.setPId(record.getAgentNo2());
                record.setPName(record.getAgentName2());
            }else if (record.getAgentNo().equals(record.getAgentNo2())) {
                record.setAgentName(record.getAgentName2());
                record.setPId(record.getAgentNo1());
                record.setPName(record.getAgentName1());
            }else if (record.getAgentNo().equals(record.getAgentNo1())) {
                record.setAgentName(record.getAgentName1());
            }
        }else {
            record.setAgentNo("自然流量");
            record.setAgentName("自然流量");
            record.setPId("自然流量");
            record.setPName("自然流量");
        }
    }

    /**
     * 会员通报（机构明细）分页列表
     * @param iPage
     * @param statMemberNumDTO
     * @return
     */
    public IPage<StatMemberNumVO> getAgentDetails(IPage iPage, StatMemberNumDTO statMemberNumDTO) {
        if (ObjectUtils.isEmpty(statMemberNumDTO.getLiteAppId())) {
            throw new BizException("请选择要查询的小程序");
        }
        if (ObjectUtils.isEmpty(statMemberNumDTO.getStatDate())) {
            statMemberNumDTO.setStatDate(DateUtil.beginOfDay(DateUtil.offsetDay(DateUtil.date(), -1)));
        }

        if (ObjectUtils.isNotEmpty(statMemberNumDTO.getAgentNo())) {
            statMemberNumDTO.setAgentNo(null);
            List<String> agentNos = agentInfoService.queryAllSubAgentNo(statMemberNumDTO.getAgentNo());
            agentNos.add(null);
            statMemberNumDTO.setAgentNoList(agentNos);
        }
        IPage<StatMemberNumVO> statMemberNumVOIPage = baseMapper.getAgentDetails(iPage, statMemberNumDTO);

        for (StatMemberNumVO record : statMemberNumVOIPage.getRecords()) {
            setAgentName(record);
        }
        return statMemberNumVOIPage;
    }

    /**
     * 郑邮享会员发展情况通报列表
     * @param statMemberNumDTO
     * @return
     */
    public StatMemberNumVO getDevelopmentSituation(StatMemberNumDTO statMemberNumDTO) {
        if (ObjectUtils.isEmpty(statMemberNumDTO.getLiteAppId())) {
            throw new BizException("请选择要查询的小程序");
        }
        if (ObjectUtils.isEmpty(statMemberNumDTO.getStatDate())) {
            statMemberNumDTO.setStatDate(DateUtil.beginOfDay(DateUtil.offsetDay(DateUtil.date(), -1)));
        }

        if (ObjectUtils.isNotEmpty(statMemberNumDTO.getAgentNo())) {
            AgentInfoVO agentInfos = agentInfoService.getAgentInfos(statMemberNumDTO.getAgentNo());
            List<String> agentNos = new ArrayList<>();
            if (ObjectUtils.isNotEmpty(agentInfos.getChildren())) {
                agentNos = agentInfos.getChildren().stream().map(AgentInfoVO::getAgentNo).collect(Collectors.toList());
            }
            agentNos.add(statMemberNumDTO.getAgentNo());
            agentNos.add(null);
            statMemberNumDTO.setAgentNoList(agentNos);
            statMemberNumDTO.setTotalAgentNo(statMemberNumDTO.getAgentNo());
            statMemberNumDTO.setAgentNo(null);
        }else {
            AgentAppEntity agentApp = agentAppService.getOne(AgentAppEntity.gw().eq(AgentAppEntity::getAppId, statMemberNumDTO.getLiteAppId()));
            if (ObjectUtils.isEmpty(agentApp)) {
                throw new BizException("未查询到小程序归属机构");
            }
            statMemberNumDTO.setTotalAgentNo(agentApp.getAgentNo());
            statMemberNumDTO.setLevel(agentInfoService.getAgentInfo(statMemberNumDTO.getTotalAgentNo()).getLevel() + 1);
        }
        List<StatMemberNumVO> statMemberNumVOList = baseMapper.getAgentDetails(statMemberNumDTO);

        for (StatMemberNumVO record : statMemberNumVOList) {
            setAgentName(record);
            Integer nextAgentNum = getDefaultValue(record.getNextAgentNum());
            record.setTotalMemberNumAvg(record.getTotalMemberNum() / nextAgentNum);
            record.setLastWeekMemberNumAvg(record.getLastWeekMemberNum() / nextAgentNum);
            record.setMonthMemberNumAvg(record.getMonthMemberNum() / nextAgentNum);
            record.setYearMemberNumAvg(record.getYearMemberNum() / nextAgentNum);
            record.setNewMemberNum(record.getTotalMemberNum() - record.getTotalSyncMemberNum());
            record.setTotalSyncMemberRatio(new BigDecimal(record.getTotalSyncMemberNum()).divide(new BigDecimal(getDefaultValue(record.getTotalMemberNum())), 2, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2));
            record.setTotalCstmMemberRatio(new BigDecimal(record.getTotalCstmMemberNum()).divide(new BigDecimal(getDefaultValue(record.getTotalMemberNum())), 2, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2));
        }
        StatMemberNumVO statMemberNumVO = new StatMemberNumVO();
        statMemberNumVO.setTotalStatMemberNumVO(statMemberNumVOList.stream().filter(item -> statMemberNumDTO.getTotalAgentNo().equals(item.getAgentNo())).findFirst().orElse(null));
        statMemberNumVO.setStatMemberNumVOList(statMemberNumVOList.stream().filter(item -> !statMemberNumDTO.getTotalAgentNo().equals(item.getAgentNo())).toList());

        StringBuilder titles = new StringBuilder("郑邮享会员发展情况通报：截止");
        titles.append(DateUtil.format(statMemberNumDTO.getStatDate(), "MM月dd日"));
        if (ObjectUtils.isNotEmpty(statMemberNumVO.getTotalStatMemberNumVO())) {
            titles.append("，郑邮享会员");
            titles.append(new BigDecimal(statMemberNumVO.getTotalStatMemberNumVO().getTotalMemberNum()).divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP));
            titles.append("（存量会员数）万户，实名会员全市共");
            titles.append(new BigDecimal(statMemberNumVO.getTotalStatMemberNumVO().getTotalCstmMemberNum()).divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP));
            titles.append("（实名会员数）万户，认证率为");
            titles.append(statMemberNumVO.getTotalStatMemberNumVO().getTotalCstmMemberRatio());
            titles.append("%。");
            statMemberNumVO.setTitles(titles.toString());
        }
        List<String> addRecords = new ArrayList<>();
        String weekAddTop = statMemberNumVO.getStatMemberNumVOList().stream().filter(item -> ObjectUtils.isNotEmpty(item.getAgentNo())).sorted(Comparator.comparing(StatMemberNumVO::getLastWeekMemberNumAvg).reversed()).limit(3).map(StatMemberNumVO::getAgentName).collect(Collectors.joining("、"));
        String weekAddLast = statMemberNumVO.getStatMemberNumVOList().stream().filter(item -> ObjectUtils.isNotEmpty(item.getAgentNo())).sorted(Comparator.comparing(StatMemberNumVO::getLastWeekMemberNumAvg)).limit(3).map(StatMemberNumVO::getAgentName).collect(Collectors.joining("、"));
        String yearAddTop = statMemberNumVO.getStatMemberNumVOList().stream().filter(item -> ObjectUtils.isNotEmpty(item.getAgentNo())).sorted(Comparator.comparing(StatMemberNumVO::getYearMemberNumAvg).reversed()).limit(3).map(StatMemberNumVO::getAgentName).collect(Collectors.joining("、"));
        String yearAddLast = statMemberNumVO.getStatMemberNumVOList().stream().filter(item -> ObjectUtils.isNotEmpty(item.getAgentNo())).sorted(Comparator.comparing(StatMemberNumVO::getYearMemberNumAvg)).limit(3).map(StatMemberNumVO::getAgentName).collect(Collectors.joining("、"));
        addRecords.add("点均周新增前三：" + weekAddTop);
        addRecords.add("点均周新增后三：" + weekAddLast);
        addRecords.add("点均年新增前三：" + yearAddTop);
        addRecords.add("点均年新增后三：" + yearAddLast);
        statMemberNumVO.setAddRecords(addRecords);

        List<String> cstmRecords = new ArrayList<>();
        String cstmTop = statMemberNumVO.getStatMemberNumVOList().stream().filter(item -> ObjectUtils.isNotEmpty(item.getAgentNo())).sorted(Comparator.comparing(StatMemberNumVO::getTotalCstmMemberRatio).reversed()).limit(3).map(StatMemberNumVO::getAgentName).collect(Collectors.joining("、"));
        String cstmLast = statMemberNumVO.getStatMemberNumVOList().stream().filter(item -> ObjectUtils.isNotEmpty(item.getAgentNo())).sorted(Comparator.comparing(StatMemberNumVO::getTotalCstmMemberRatio)).limit(3).map(StatMemberNumVO::getAgentName).collect(Collectors.joining("、"));
        cstmRecords.add("点均周新增前三：" + cstmTop);
        cstmRecords.add("点均周新增后三：" + cstmLast);
        statMemberNumVO.setCstmRecords(cstmRecords);

        return statMemberNumVO;
    }

    /**
     * 获取最近天数的统计数据
     * @return
     */
    public JSONObject getMemberNumStatistics(StatMemberNumDTO statMemberNumDTO) {
        //根据机构号查询最近一周的统计结果
        List<StatMemberNumEntity> list = baseMapper.selectList(StatMemberNumEntity.gw()
                .eq(StatMemberNumEntity::getLiteAppId, statMemberNumDTO.getLiteAppId())
                .eq(StatMemberNumEntity::getAgentNo, statMemberNumDTO.getAgentNo())
                .orderByDesc(StatMemberNumEntity::getStatDate)
                .last(" limit " + STAT_DAY));
        JSONObject result = new JSONObject();
        if (CollUtil.isNotEmpty(list)) {
            list = list.stream().sorted(Comparator.comparing(StatMemberNumEntity::getStatDate)).toList();
            //获取日期，格式为MM-dd
            List<String> dateList = list.stream().map(item -> DateUtil.format(item.getStatDate(), "MM-dd")).toList();
            //获取已发展客户数
            List<Integer> totalMemberNumList = list.stream().map(StatMemberNumEntity::getTotalMemberNum).toList();
            //获取已发展实名客户数
            List<Integer> totalCstmMemberNumList = list.stream().map(StatMemberNumEntity::getTotalCstmMemberNum).toList();
            result.put("totalMemberNumList", totalMemberNumList);
            result.put("totalCstmMemberNumList", totalCstmMemberNumList);
            result.put("dateList", dateList);
        }else {
            result.put("totalMemberNumList", new int[STAT_DAY]);
            result.put("totalCstmMemberNumList", new int[STAT_DAY]);
            List<String> dateList = new ArrayList<>();
            DateTime date = DateUtil.date();
            for (int i = STAT_DAY; i > 0; i--) {
                dateList.add(DateUtil.format(DateUtil.offsetDay(date, -i), "MM-dd"));
            }
            result.put("dateList", dateList);
        }
        return result;
    }
}
